grammar V1;

script: (stmt)+;
stmt: simpleStmt | complexStmt ;
// 简单句 (2类):工具运行的原子句（即时型、监听型、定时型）
simpleStmt: intenseStmt | listenStmt | scheduleStmt | setStmt;

// 1.即时型 如：张三在喇叭帮区执行喇叭工具的发声部件，返回结果为A。
intenseStmt: Char+ place Run Char+ Tool_s Char+ Unit (Comma|(Comma paramStmt)+ Comma) Return Char+ Dot?;
// 定义工具部件参数
paramStmt: Char+ Is Char+ ;
place: At Char+ Band;

// 2.监听型
//监听型语句，如：当 在xx帮区 监听到 消息总线 设备故障 消息的类型，则 张三 在 xx帮区 执行 消息板工具 ，消息板为XXX，消息内容为XXX。
listenStmt: When place Listen MessageBus Char+ Type_sMessage Comma Then triggerStmt;
triggerStmt: notifyStmt | intenseStmt;
notifyStmt: Char+ At Char+ Band Run ChatTool Comma ChatRoom Is Char+ Comma MsgContent Is Char+ Dot?;


// 3.定时型
// (1) 周期
// 如：每1天8点，张三 在 喇叭 帮区 执行 喇叭 工具的 发声 部件，喇叭id为xx。
// (2) 延时
// 如：2小时 之后，张三 在 喇叭 帮区 执行 喇叭 工具的 发声 部件，喇叭id为xx。
scheduleStmt: timeAdverbial Comma (intenseStmt | listenStmt);
timeAdverbial: period | delay;
period: Every Char+;
delay: Char+ After;



// 复杂句 (2类): 条件句 + 循环句
complexStmt: (ifStmt | loopStmt)+;

// 1.条件句
ifStmt: If conditionStmt Comma Then simpleStmt;
conditionStmt: (Char+ Operate Char+) | ();

// 2.循环句
loopStmt: Repeat simpleStmt Char+ Times;

// 设置变量
setStmt: Set (Comma? Char+ Is value)+ Dot?;
value: (complexStmt | simpleStmt | Char+);


At: '在';
Band: '帮区';
Run: '执行' | '调用';
Tool_s: '工具的';
Unit: '部件';
Is: '为';
Return: '返回结果为';

When: '当';
Listen: '监听到';
MessageBus: '消息总线';
Type_sMessage: '消息的类型';
Then: '则';
ChatTool: '消息板工具';
ChatRoom: '消息板';
MsgContent: '消息内容';

After: '之后' | '后';
Every: '每';

If: '如果';
Operate: '大于' | '等于' | '小于';

Repeat: '重复';
Times: '次';

Set: '设置';


Comma: ',' | '，';
Dot :'.'|'。';
Char: ([a-zA-Z0-9$_] | [\u4E00-\u9FA5]);

Ws :[ \t\r\n]+ -> skip;
Comment :'//' ~[\r\n]* -> channel(HIDDEN);